﻿using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace XNET.Extension
{
    /// <summary>
    /// 字节扩展
    /// </summary>
    public static class ByteExtension
    {
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="bytes">字节数组</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this byte[] bytes)
        {
            if (bytes == null || bytes.Length <= 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 将字节数组装换为Base64字符串
        /// </summary>
        /// <param name="Input">字节数组</param>
        /// <param name="Count">要转换的字节数组长度</param>
        /// <param name="Index">开始素银</param>
        /// <param name="Options">是否插入分隔符</param>
        /// <returns></returns>
        public static string ToString(this byte[] Input, Base64FormattingOptions Options, int Index = 0, int Count = -1)
        {
            if (Count == -1)
            {
                Count = Input.Length - Index;
            }
            return Input == null ? string.Empty : Convert.ToBase64String(Input, Index, Count, Options);
        }

        /// <summary>
        /// 将字节数组转换为字符串
        /// </summary>
        /// <param name="Input">字节数组</param>
        /// <param name="EncodingUsing">转换编码(默认UTF8)</param>
        /// <param name="Count">要转换的字节数组长度</param>
        /// <param name="Index">开始索引</param>
        /// <returns></returns>
        public static string ToString(this byte[] Input, Encoding EncodingUsing, int Index = 0, int Count = -1)
        {
            if (Input == null)
            {
                return string.Empty;
            }
            if (Count == -1)
            {
                Count = Input.Length - Index;
            }
            return EncodingUsing.Check(new UTF8Encoding()).GetString(Input, Index, Count);
        }

        /// <summary>
        /// 是否指定类型
        /// </summary>
        /// <param name="Value">字符</param>
        /// <param name="CharacterType">类型</param>
        /// <returns></returns>
        public static bool Is(this char Value, CharIs CharacterType)
        {
            if (CharacterType.HasFlag(CharIs.WhiteSpace))
            {
                return char.IsWhiteSpace(Value);
            }
            if (CharacterType.HasFlag(CharIs.Upper))
            {
                return char.IsUpper(Value);
            }
            if (CharacterType.HasFlag(CharIs.Symbol))
            {
                return char.IsSymbol(Value);
            }
            if (CharacterType.HasFlag(CharIs.Surrogate))
            {
                return char.IsSurrogate(Value);
            }
            if (CharacterType.HasFlag(CharIs.Punctuation))
            {
                return char.IsPunctuation(Value);
            }
            if (CharacterType.HasFlag(CharIs.Number))
            {
                return char.IsNumber(Value);
            }
            if (CharacterType.HasFlag(CharIs.LowSurrogate))
            {
                return char.IsLowSurrogate(Value);
            }
            if (CharacterType.HasFlag(CharIs.Lower))
            {
                return char.IsLower(Value);
            }
            if (CharacterType.HasFlag(CharIs.LetterOrDigit))
            {
                return char.IsLetterOrDigit(Value);
            }
            if (CharacterType.HasFlag(CharIs.Letter))
            {
                return char.IsLetter(Value);
            }
            if (CharacterType.HasFlag(CharIs.HighSurrogate))
            {
                return char.IsHighSurrogate(Value);
            }
            if (CharacterType.HasFlag(CharIs.Digit))
            {
                return char.IsDigit(Value);
            }
            if (CharacterType.HasFlag(CharIs.Control))
            {
                return char.IsControl(Value);
            }
            return false;
        }

        /// <summary>
        /// 确定一个字节数组是否Unicode编码
        /// </summary>
        /// <param name="Input">字节数组</param>
        /// <returns>True 是unicode编码, false 则不是</returns>
        public static bool IsUnicode(this byte[] Input)
        {
            return Input == null ? true : Input.ToString(new UnicodeEncoding()).Is(StringCompare.Unicode);
        }

        /// <summary>
        /// 将字节转换为对象
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="bytes">字节</param>
        /// <returns></returns>
        public static T ByteToObject<T>(this byte[] bytes)
        {
            if (bytes.IsNullOrEmpty()) return default(T);

            try
            {
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    IFormatter formatter = new BinaryFormatter();
                    return (T)formatter.Deserialize(ms);
                }
            }
            catch 
            {
                return default(T);
            }
        }
    }

    /// <summary>
    /// 字符类型
    /// </summary>
    [Flags]
    public enum CharIs
    {
        /// <summary>
        /// 控制字符
        /// </summary>
        Control = 4096,
        /// <summary>
        /// 十进制数字字符
        /// </summary>
        Digit = 2048,
        /// <summary>
        /// 高级代理项
        /// </summary>
        HighSurrogate = 1024,
        /// <summary>
        /// 分类为Unicode
        /// </summary>
        Letter = 512,
        /// <summary>
        /// 字母或者十进制
        /// </summary>
        LetterOrDigit = 256,
        /// <summary>
        /// 小写字母
        /// </summary>
        Lower = 128,
        /// <summary>
        /// 低代理项
        /// </summary>
        LowSurrogate = 64,
        /// <summary>
        /// 数字
        /// </summary>
        Number = 32,
        /// <summary>
        /// 标点符合类别
        /// </summary>
        Punctuation = 16,
        /// <summary>
        /// 代理项码位
        /// </summary>
        Surrogate = 8,
        /// <summary>
        /// 符号字符
        /// </summary>
        Symbol = 4,
        /// <summary>
        /// 大写
        /// </summary>
        Upper = 2,
        /// <summary>
        /// 空白
        /// </summary>
        WhiteSpace = 1
    }
}
